﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Abp.Configuration;
using Abp.Domain.Repositories;
using Abp.Domain.Uow;
using Abp.Extensions;
using Abp.UI;
using IdentityServer4.Validation;
using JetBrains.Annotations;
using NClone;

namespace Camc.OutsourceProcession.Order
{
	public class ProductionOrderManager:OutsourceProcessionDomainServiceBase, IProductionOrderManager
	{
		private readonly IRepository<ProductionOrder, long> _productionOrderRepository;
		private readonly IRepository<ExecuteHistory, long> _executeHistoryRepository;

		public ProductionOrderManager(IRepository<ProductionOrder, long> productionOrderRepository, IRepository<ExecuteHistory, long> executeHistoryOrderRepository)
		{
			_productionOrderRepository = productionOrderRepository;
			_executeHistoryRepository = executeHistoryOrderRepository;
		}

		/// <summary>
		/// 创建任务
		/// </summary>
		public long CreateOrder(string taskCode,string taskKey,int quantity,DateTime deliveryTime, string companyId)
		{
			var newOrder = new ProductionOrder();
			newOrder.TaskCodeForOutside = taskCode;
			newOrder.TaskKey = taskKey;
			newOrder.Quantity = quantity;
			newOrder.DeliveryTime = deliveryTime;
			newOrder.CompanyCode = companyId;

			var productionOrderId = _productionOrderRepository.InsertAndGetId(newOrder);

			_executeHistoryRepository.Insert(new ExecuteHistory() { ProductionOrderId = productionOrderId, Operation = "发布" });


			return productionOrderId;
		}

		/// <summary>
		/// 暂停
		/// </summary>
		public void Suspend(long productionOrderId)
		{

			
			var productionOrder = _productionOrderRepository.Get(productionOrderId);
			productionOrder.SetSuspend();

			_executeHistoryRepository.Insert(new ExecuteHistory() { ProductionOrderId = productionOrderId, Operation = "暂停" });

		}

		/// <summary>
		/// 正常
		/// </summary>
		public void Normal(long productionOrderId)
		{
			var productionOrder = _productionOrderRepository.Get(productionOrderId) ?? throw new UserFriendlyException("没有该任务。");
			productionOrder.SetNormal();

			_executeHistoryRepository.Insert(new ExecuteHistory() { ProductionOrderId = productionOrderId, Operation = "正常" });
		}

		/// <summary>
		/// 作废
		/// </summary>
		public void Dispose(long productionOrderId)
		{
			var productionOrder = _productionOrderRepository.Get(productionOrderId) ?? throw new UserFriendlyException("没有该任务。");
			productionOrder.SetDispose();

			_executeHistoryRepository.Insert(new ExecuteHistory() { ProductionOrderId = productionOrderId, Operation = "作废" });
		}
		/// <summary>
		/// 报废
		/// </summary>
		public void Scrap(long productionOrderId)
		{
			var productionOrder = _productionOrderRepository.Get(productionOrderId) ?? throw new UserFriendlyException("没有该任务。");
			productionOrder.SetScrap();

			_executeHistoryRepository.Insert(new ExecuteHistory() { ProductionOrderId = productionOrderId, Operation = "报废" });
		}


		/// <summary>
		/// 取回任务（从制造商手中取回任务）
		/// </summary>
		public void Renew(long productionOrderId,string companyId)
		{
			var productionOrder = _productionOrderRepository.Get(productionOrderId) ?? throw new UserFriendlyException("没有该任务。");
			productionOrder.SetRenew(companyId);

			_executeHistoryRepository.Insert(new ExecuteHistory() { ProductionOrderId = productionOrderId, Operation = "取回" });
		}

		/// <summary>
		/// 接收
		/// </summary>
		public void Receive(long productionOrderId, string companyId)
		{
			using (CurrentUnitOfWork.DisableFilter("MayHaveCompanyCode"))
			{
				var productionOrder = _productionOrderRepository.Get(productionOrderId) ??
				                      throw new UserFriendlyException("没有该任务。");
				productionOrder.SetReceive(companyId);

				_executeHistoryRepository.Insert(new ExecuteHistory()
					{ProductionOrderId = productionOrderId, Operation = "接收"});
			}
		}

        /// <summary>
        /// 加工
        /// </summary>
        public void Process(long productionOrderId, string equipmentDisplayName)
        {

          
                var productionOrder = _productionOrderRepository.Get(productionOrderId) ??
                                      throw new UserFriendlyException("没有该任务。");
                productionOrder.SetProcess();

                _executeHistoryRepository.Insert(new ExecuteHistory()
                    {ProductionOrderId = productionOrderId, Operation = "加工", ProcessLocation = equipmentDisplayName});
            
        }

        /// <summary>
		/// 交付
		/// </summary>
		public void Deliver(long productionOrderId)
		{
          
                var productionOrder = _productionOrderRepository.Get(productionOrderId) ??
                                      throw new UserFriendlyException("没有该任务。");
                productionOrder.SetDeliver();

                _executeHistoryRepository.Insert(new ExecuteHistory()
                    {ProductionOrderId = productionOrderId, Operation = "交接"});
            
        }

		/// <summary>
		/// 分解任务
		/// </summary>
		/// <param name="productionOrderId"></param>
		/// <param name="separateCountList"></param>
		/// <returns></returns>
		public List<long> Separate(long productionOrderId,params int[] separateCountList)
		{
			var productionOrder = _productionOrderRepository.Get(productionOrderId) ?? throw new UserFriendlyException("没有该任务。");

			var result = new List<long>();
			if (separateCountList?.Sum() != productionOrder.Quantity)
			{
				throw new UserFriendlyException("拆解数量不对，请核对。");
			}
			else
			{
				
				foreach (var separateCount in separateCountList)
				{
					var newOrderId = CreateOrderFromOldWithQuantity(productionOrder, separateCount);
                    _executeHistoryRepository.Insert(new ExecuteHistory()
                    {
                        ProductionOrderId = newOrderId,
                        Operation =
                        $"拆分,从{productionOrder.Quantity}到{separateCount}"
                    });
                    result.Add(newOrderId);
				}
				productionOrder.SetDispose();
			}

			return result;
		}


		private long CreateOrderFromOldWithQuantity(ProductionOrder oldOrder,int count)
		{
			var newProductionOrder = Clone.ObjectGraph<ProductionOrder>(oldOrder);
            newProductionOrder.Id = new ProductionOrder().Id;


            newProductionOrder.Quantity = count;

			var newProductionOrderId = _productionOrderRepository.InsertAndGetId(newProductionOrder);

			var oldHistories = _executeHistoryRepository.GetAll().Where(c=>c.ProductionOrderId == oldOrder.Id).ToList();
			// var newhistory = Clone.ObjectIgnoringConventions(oldHistories);

			//foreach (var history in oldHistories)
			//         {

			//        var     newhistory = Clone.ObjectGraph<ExecuteHistory>(history);
			//        newhistory.Id = new ExecuteHistory().Id;

			//	_executeHistoryRepository.Insert(newhistory);
			//}

            foreach (var history in oldHistories)
            {
              //  var newhistory = Clone.ObjectGraph<ExecuteHistory>(history);
              //var newhistory = new ExecuteHistory();
			 
              //  newhistory.ProductionOrderId = newProductionOrderId;
              //  newhistory.Operation = history.Operation;
              //  newhistory.ProcessLocation = history.ProcessLocation;
				_executeHistoryRepository.Insert(new ExecuteHistory()
                { ProductionOrderId = newProductionOrderId,
                    Operation = history.Operation,
                    ProcessLocation = history.ProcessLocation
				});
            }

			return newProductionOrderId;
		}
	}

	
}
